import React, { useState, useMemo, useCallback, useRef } from 'react';
import ModalView from './ModalView';
import BaseSelect from './BaseSelect';
import GridCellEditWrapper from '../gridcelleditwrapper';
import type { SelectType } from './BaseSelect';
import type { ModalPositionSize } from 'gantd/lib/modal/interface';
import type { Columns, RowSelection } from 'gantd/lib/grid/interface';
import type { OnSearch } from '@/components/searchform';
import type { SearchFormSchema, CustomComponent } from '@/components/searchform/interface';
import type { UISchema } from 'gantd/lib/schema-form';
import { getGantPopupContainer } from '@/utils/utils';
interface ViewProps {
  //modal
  title: string | React.ReactDOM | Element;
  wrapClassName?: string;
  zIndex?: number;
  itemState?: ModalPositionSize;
  footerLeftExtra?: React.ReactDOM;
  footerRightExtra?: React.ReactDOM;
  onModalVisibleChange?: (visible: boolean) => void;
  //searchForm
  viewKey: string;
  searchFormTitle?: string | React.ReactDOM;
  initParams?: any;
  schema?: SearchFormSchema;
  uiSchema?: UISchema;
  customComponents?: CustomComponent[];
  onSearch?: OnSearch;
  //grid
  dataSource: any[];
  columns: Columns[];
  loading?: boolean;
  rowSelection?: RowSelection;
  [propName: string]: any;
}

interface LoupeSelectProps {
  value?: string | string[];
  multiple?: boolean;
  valueProp?: string;
  labelProp?: string;
  confirmLoading?: boolean;
  viewProps?: ViewProps;
  componentType?: SelectType;
  children?: (props: any) => React.ReactNode;
  onChange?: (value: string | number | string[] | number[], selectedRows: any, fromModalChange?: boolean) => void;
  [propName: string]: any;
}

const LoupeSelect = (props: LoupeSelectProps) => {
  const {
    value,
    multiple,
    valueProp,
    labelProp,
    onChange,
    viewProps,
    children,
    componentType,
    confirmLoading,
    onBlur,
    ...restProps
  } = props;

  const [visible, setVisible] = useState(false);
  const foucsRef = useRef(restProps.autoFocus);
  const [InputDataSource, SetInputDataSource] = useState<any[]>([]);
  const selectApiRef: any = useRef(null);
  //改变弹窗状态
  const changeVisibleState = useCallback((visible = false) => {
    setVisible(visible);
  }, []);

  //更新下拉 最新选择storage
  const updateSelectStorage = useCallback((selectedRows: any[]) => {
    if (!selectedRows.length || !selectApiRef.current) return;
    const { updateStorage } = selectApiRef.current;
    updateStorage && updateStorage(selectedRows);
  }, []);

  //弹窗onOK事件
  const handleOk = useCallback(
    (selectedRowKeys: string[], selectedRows: any[]) => {
      if (componentType == 'Input') {
        SetInputDataSource(selectedRows || []);
      }
      updateSelectStorage(selectedRows);
      const ret: any = multiple ? selectedRowKeys : selectedRowKeys[0];
      onChange && onChange(ret, selectedRows, true);
      setVisible(false);
    },
    [value, multiple, onChange, componentType],
  );

  const selectProps = useMemo(() => {
    if (componentType == 'Input') {
      return {
        dataSource: InputDataSource,
        ...restProps,
      };
    } else {
      return restProps;
    }
  }, [componentType, InputDataSource, restProps]);
  const selectBlur = useCallback(() => {
    setTimeout(() => {
      if (foucsRef.current) return;
      onBlur && onBlur();
    }, 20);
  }, [onBlur]);
  const modalViewProps = useMemo(() => {
    return {
      value: multiple ? value : value && [value],
      visible,
      multiple,
      valueProp,
      labelProp,
      confirmLoading,
      onOk: handleOk,
      onCancel: changeVisibleState.bind(null, false),
      ...viewProps,
    };
  }, [multiple, value, visible, valueProp, labelProp, confirmLoading, handleOk, changeVisibleState, viewProps]);

  return (
    <GridCellEditWrapper autoFocus onBlur={selectBlur} visible={visible}>
      <BaseSelect
        getPopupContainer={getGantPopupContainer}
        value={value}
        multiple={multiple}
        valueProp={valueProp}
        labelProp={labelProp}
        componentType={componentType}
        onChange={onChange}
        onLoupeClick={changeVisibleState.bind(null, true)}
        onApiRef={(ref: any) => (selectApiRef.current = ref)}
        onBlur={() => (foucsRef.current = false)}
        onFocus={() => {
          foucsRef.current = true;
        }}
        {...selectProps}
      />
      {children ? children(modalViewProps) : <ModalView {...modalViewProps} />}
    </GridCellEditWrapper>
  );
};

LoupeSelect.defaultProps = {
  multiple: false,
  valueProp: 'id',
  labelProp: 'name',
  viewProps: {},
};

export default LoupeSelect;
